use std::env;
use std::fs;
use std::process;
use minigrep::Config2;

fn main() {
    println!("Hello, world!");
    let config = Config2::new(env::args()).unwrap_or_else(|err| {
        eprintln!("Problem parsing arguments: {}", err);
        process::exit(1);
    });
    if let Err(e) = config.run() {
        eprintln!("Application error: {}", e);
        process::exit(1);
    }

    let args: Vec<String> = env::args().collect();// collect all arguments into a vector
    println!("========== start minigrep ==========");
    if let Err(e) = minigrep::run(minigrep::Config1::new(&args).unwrap()) {
        eprintln!("Application error: {}", e);
        process::exit(1);
   }

    println!("========== end minigrep ==========");

    let args: Vec<String> = env::args().collect();// collect all arguments into a vector

    // let query = &args[1]; // get the query
    // let filename = &args[2]; // get the filename
    // let (query, filename) = parse_config_1(&args); // get the query and filename
    
    // let config = parse_config(&args); // get the query and filename
    // let config = Config::new(&args);
    let config = Config::new(&args).unwrap_or_else(|err| {
        eprintln!("Problem parsing arguments: {}", err);
        process::exit(1);
    });
    let filename = config.filename;
    let query = config.query;
    println!("Searching for {} in {}", query, filename);
    
    println!("{:?}",args);
    
    
    let contents = fs::read_to_string(filename).expect("Something went wrong reading the file");
    println!("With text:\n{}", contents);
}

#[allow(dead_code)]
/// 解析配置参数
///
/// # Arguments
///
/// * `args` - 一个字符串切片数组，包含命令行参数
///
/// # Returns
///
/// 返回一个元组，第一个元素是查询字符串，第二个元素是文件名
///
/// # Panics
///
/// 当 `args` 数组长度不足以包含查询字符串和文件名时，可能会发生索引越界
fn parse_config_1(args: &[String]) -> (&str, &str) {
    // 提取查询字符串
    let query = &args[1];
    // 提取文件名
    let filename = &args[2];

    // 返回查询字符串和文件名的元组
    (query, filename)
}

struct Config {
    query: String,
    filename: String,
}

impl Config {
    // fn new(args: &[String]) -> Config {
    //     if args.len() < 3 {
    //         panic!("not enough arguments");
    //     }
    //     let query = args[1].clone();
    //     let filename = args[2].clone();
    //     Config { query, filename }
    // }

    fn new(args: &[String]) -> Result<Config, &'static str> {
        if args.len() < 3 {
            return Err("not enough arguments");
        }
        let query = args[1].clone();
        let filename = args[2].clone();

        Ok(Config { query, filename })
    }
}

#[allow(dead_code)]
/// 解析配置参数
///
/// # Parameters
///
/// * `args`: 包含命令行参数的字符串向量。预期至少包含两个元素：
///   - 第一个元素（索引为1）是查询字符串。
///   - 第二个元素（索引为2）是文件名。
///
/// # Returns
///
/// 返回一个`Config`结构体实例，其中包含从命令行参数中提取的`query`和`filename`。
/// 
/// # Panics
/// 
/// 当`args`数组不满足预期长度时，该函数可能会因为索引访问越界而引发`panic`。
fn parse_config(args: &[String]) -> Config {
    // 克隆第二个命令行参数作为查询字符串
    let query = args[1].clone();
    // 克隆第三个命令行参数作为文件名
    let filename = args[2].clone();

    // 使用提取的值构造并返回Config结构体实例
    Config { query, filename }
}
